#include "application.h"
/* Exit callback */
int exit_callback(int arg1, int arg2, void *argp)
{
	Application *app = (Application*)argp;
	app->running = 0;
	return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
	int cbid;
	cbid = sceKernelCreateCallback("Exit Callback", exit_callback, *(void**)argp);
	sceKernelRegisterExitCallback(cbid);

	sceKernelSleepThreadCB();

	return 0;
}

/* Sets up the callback thread and returns its thread id */
int Application::SetupCallbacks(void)
{
	int thid = 0;

	thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
	if(thid >= 0)
	{
		Application *app = this;
		sceKernelStartThread(thid, 4, (void*)&app);
	}

	return thid;
}

Application::Application(int argc, char *argv[]){
	SetupCallbacks();
}

void Application::run(){
	int result, oldCpu, oldBus;
	oldCpu = scePowerGetCpuClockFrequency();
	oldBus = scePowerGetBusClockFrequency();
	screen.setClockFontStyle(3.5f, screen.WHITE, screen.BLACK, 0);
	pspTime time;
	int powerTick = 0;
	char *DaysOfTheWeek[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
	char *MonthsOfTheYear[] = {"Neverary", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
	float x = 0, y = 50, str1Len, str2Len, fixed;
	char timeStr1[8], *fixedSep, timeStr2[8];
	char *sep = ":", *space = " ";
	float colL, spL;
	colL = screen.clockFontMeasureText(sep);
	spL = screen.clockFontMeasureText(space);
	fixed = colL>spL?colL:spL;
	result = scePowerSetClockFrequency(19, 2, 1);		
//	printf("scePowerSetClockFrequency=0x%x", result);
//	scePowerSetCpuClockFrequency(2);
//	scePowerSetBusClockFrequency(1);
	running = 1;
	char msg[128];
	char date[128];
	char *dayEnd;
	int charger, battery, charging, chargingStatus, lowBattery, batteryLifePercent, batteryLifeTime, batteryTemp, batteryVolt;
	float cpuClockFreq, busClockFreq;
	while (running){
		sceRtcGetCurrentClockLocalTime(&time);
		if (powerTick != time.minutes){
			scePowerTick(PSP_POWER_TICK_ALL);
			powerTick = time.minutes;
			int mod;
			if ((mod = time.day%10) > 3){
				dayEnd = "th";
			}
			else if (time.day > 3 && time.day < 21){
				dayEnd = "th";
			}			
//			else dayEnd = (mod > 2)?"rd":(mod > 1)?"nd":"st";
			else if (mod > 2){
				dayEnd = "rd";
			}
			else if (mod > 1){
				dayEnd = "nd";
			}
			else{
				dayEnd = "st";
			}
		}
		sprintf(timeStr1, "%2d:%02d", time.hour==0?12:time.hour>12?time.hour-12:time.hour, time.minutes);
		fixedSep = time.microseconds<500000?space:sep;
		sprintf(timeStr2, "%02d %s", time.seconds, time.hour<12?"AM":"PM");
		sprintf(date, "%s %d%s %s %d", DaysOfTheWeek[sceRtcGetDayOfWeek(time.year, time.month, time.day)], time.day, dayEnd, MonthsOfTheYear[time.month], time.year);
		str1Len = screen.clockFontMeasureText(timeStr1);
		str2Len = screen.clockFontMeasureText(timeStr2);
		x = (SCR_WIDTHF-(str1Len + fixed + str2Len))/2.0f;y = 50;
		screen.guStart();
		x += screen.clockPrint(x, y, timeStr1); 
		screen.clockPrint(x, y, fixedSep); 
		x += fixed;
		screen.clockPrint(x, y, timeStr2);

		x = 0;y = 90;
		screen.setInfoFontStyle(1.5f, screen.WHITE, screen.BLACK, 0);
		screen.infoPrint(x, y, date);

		charger = scePowerIsPowerOnline();
		battery = scePowerIsBatteryExist();
		charging = scePowerIsBatteryCharging();
//		chargingStatus = scePowerGetBatteryChargingStatus();
		lowBattery = scePowerIsLowBattery();
		batteryLifePercent = scePowerGetBatteryLifePercent();
		batteryLifeTime = scePowerGetBatteryLifeTime();
		batteryTemp = scePowerGetBatteryTemp();
		batteryVolt = scePowerGetBatteryVolt();
		busClockFreq = scePowerGetBusClockFrequencyFloat();
		cpuClockFreq = scePowerGetCpuClockFrequencyFloat();
		


		x = 0;y = 120;
		screen.setInfoFontStyle(1.0f, screen.WHITE, screen.BLACK, 0);		
		if (battery == 1){
			char mins[8];
			if (batteryLifeTime == 0){
				sprintf(mins, "-");
			}
			else{
				sprintf(mins, "%d", batteryLifeTime); 
			}
			sprintf(msg, "Battery life: %s minutes(%d%%)", mins, batteryLifePercent);
			screen.infoPrint(x, y, msg);
			x = 0;y += vSpacing1;
		}

		sprintf(msg, "Battery %spresent%s%s%s%s", battery==1?"":"not ", lowBattery|charging==1?"(":"", charging==1?" 'charging' ":"", lowBattery==1?" 'low battery' ":"", lowBattery|charging==1?")":"");
		screen.infoPrint(x, y, msg);
		x = 0;y += vSpacing1;

		sprintf(msg, "Charger %spresent", charger==1?" ":"not ");
		screen.infoPrint(x, y, msg);
		x = 0;y += vSpacing1;

		if (battery == 1){
			sprintf(msg, "Battery temperature: %d degrees", batteryTemp);
			screen.infoPrint(x, y, msg);
			x = 0;y += vSpacing1;

			sprintf(msg, "Battery volt level: %d", batteryVolt);
			screen.infoPrint(x, y, msg);
			x = 0;y += vSpacing1;
		}

		sprintf(msg, "Cpu clock frequency: %f MHz", cpuClockFreq);
		screen.infoPrint(x, y, msg);
		x = 0;y += vSpacing1;

		sprintf(msg, "Bus clock frequency: %f MHz", busClockFreq);
		screen.infoPrint(x, y, msg);
		x = 0;y += vSpacing1;
		
		screen.guFinish();
	}

}
void Application::done(){
	sceKernelExitGame();
}


	